package com.aplink.dellcommercial.webservices;

import android.annotation.TargetApi;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;

import com.aplink.dellcommercial.configuration.DellController;
import com.aplink.generic.pojo.ObjPropInfo;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class WebServiceHelper {
    private volatile static WebServiceHelper uniqueInstance;
    public static final int MAX_SIZE_POOL = 10;

    private final Map<String, HttpTask> mPoolExcutingTask;

    private final Queue<HttpTask> mWaitingTask;

    public static WebServiceHelper getInstance() {
        if ( uniqueInstance == null ) {
            synchronized ( WebServiceHelper.class ) {
                if ( uniqueInstance == null ) {
                    uniqueInstance = new WebServiceHelper();
                }
            }
        }
        return uniqueInstance;
    }

    private WebServiceHelper() {
        this.mPoolExcutingTask = new LinkedHashMap<String, HttpTask>(
                MAX_SIZE_POOL );
        this.mWaitingTask = new ConcurrentLinkedQueue<HttpTask>();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void excuteRequest( String url, MethodParams methodparam,
                                Activity activity, Handler handler,
                                ArrayList<ObjPropInfo> objPropInfos ) {
        final HttpTask httpTask = new HttpTask( url, methodparam,
                this.mPoolExcutingTask, activity, handler, objPropInfos );
        if ( this.mPoolExcutingTask.get( url ) == null ) {
            this.mPoolExcutingTask.put( url, httpTask );
            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
                httpTask.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR );
            } else {
                httpTask.execute();
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void excuteRequest( String url, String data,
                                MethodParams methodparam, Activity activity, Handler handler ) {
        if ( this.mPoolExcutingTask.get( url ) == null ) {
            final HttpTask task = new HttpTask( url, methodparam,
                    this.mPoolExcutingTask, data, activity, handler );
            this.mPoolExcutingTask.put( url, task );
            if ( android.os.Build.VERSION.SDK_INT >= 11 ) {
                task.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR,
                        (Void) null );
            } else {
                task.execute( (Void) null );
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void excuteRequest( String url, String data,
                                MethodParams methodparam, Activity activity, Handler handler,
                                ArrayList<ObjPropInfo> objPropInfos ) {
        if ( this.mPoolExcutingTask.get( url ) == null ) {
            final HttpTask task = new HttpTask( url, methodparam,
                    this.mPoolExcutingTask, data, activity, handler,
                    objPropInfos );
            this.mPoolExcutingTask.put( url, task );
            if ( android.os.Build.VERSION.SDK_INT >= 11 ) {
                task.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR,
                        (Void) null );
            } else {
                task.execute( (Void) null );
            }
        }
    }

    public Map<String, HttpTask> getPoolExcutingTask() {
        return this.mPoolExcutingTask;
    }

    public void getPromotion( Activity activity, Handler handler,
                              ArrayList<ObjPropInfo> promotions ) {
        final String token = DellController.getInstance().getJsonAccountToken();
        final Map<String, String> param = new HashMap<String, String>();
        param.put( "PartnerID", DellController.getInstance().getAccountId() );
        final JSONObject json = new JSONObject( param );
        this.excuteRequest( Urls.GET_PROMOTION,
                String.format( "token=%s&jsonValue=%s", token, json ),
                new MethodParams( Methods.GET_PROMOTION ), activity, handler,
                promotions );
    }

    public void changePassword( Activity activity, Handler handler,
                                String email, String password ) {
        String token = DellController.getInstance().getJsonAccountToken();
        HashMap<String, String> params = new HashMap<String, String>();
        params.put( "username", email );
        params.put( "password", password );
        JSONObject json = new JSONObject( params );
        excuteRequest( Urls.CHANGE_PASS,
                String.format( "jsonValue=%s&token=%s", json.toString(), token ),
                new MethodParams( Methods.CHANGE_PASSWORD ), activity, handler );
    }

    public void getProduct( Activity activity, Handler handler,
                            ArrayList<ObjPropInfo> promotions ) {
        String token = DellController.getInstance().getJsonAccountToken();
        Map<String, String> param = new HashMap<String, String>();
        param.put( "PartnerID", DellController.getInstance().getAccountId() );
        JSONObject json = new JSONObject( param );
        excuteRequest( Urls.GET_PRODUCT_IMAGE,
                String.format( "token=%s&jsonValue=%s", token, json ),
                new MethodParams( Methods.GET_PRODUCT ), activity, handler,
                promotions );
    }

    public void getPriceBook( Activity activity, Handler handler,
                              ArrayList<ObjPropInfo> pricebooks ) {
        String token = DellController.getInstance().getJsonAccountToken();
        Map<String, String> param = new HashMap<String, String>();
        param.put( "PartnerID", DellController.getInstance().getAccountId() );
        JSONObject json = new JSONObject( param );
        this.excuteRequest( Urls.GET_PRICE_BOOK,
                String.format( "token=%s&jsonValue=%s", token, json ),
                new MethodParams( Methods.GET_PRICEBOOK ), activity, handler,
                pricebooks );
    }

    public void getUserProfiles( Activity activity, Handler handler,
                                 ArrayList<ObjPropInfo> userProfiles ) {
        final String token = DellController.getInstance().getJsonAccountToken();
        final String contactId = DellController.getInstance().getContactID();
        final String url = String.format( Urls.GET_USERINFOR, "\"ContactID\"",
                "\"" + contactId + "\"", token );
        this.excuteRequest( url, new MethodParams( Methods.GET_CUSTOMER_INFO ),
                activity, handler, userProfiles );
    }

    public Queue<HttpTask> getWaitingTask() {
        return this.mWaitingTask;
    }

    public void login( Activity activity, Handler handler, String email,
                       String password, ArrayList<ObjPropInfo> userLoginInfos ) {
        this.excuteRequest( String.format( Urls.LOGIN, String.format(
                "{\"username\":\"%s\",\"password\":\"%s\"}", email, password ) ),
                new MethodParams( Methods.LOGIN ), activity, handler,
                userLoginInfos );
    }

    public void resetPassword( Activity activity, Handler handler, String email,
                               ArrayList<ObjPropInfo> userLoginInfos ) {
        final HashMap<String, String> params = new HashMap<String, String>();
        params.put( "email", email );
        final JSONObject json = new JSONObject( params );
        this.excuteRequest( Urls.FORGET_PASS,
                String.format( "jsonValue=%s", json.toString() ),
                new MethodParams( Methods.resetPass ), activity, handler,
                userLoginInfos );
    }

    public void getAllTips( Activity activity, Handler handler,
                            ArrayList<ObjPropInfo> tipObjPropInfos ) {
        String token = DellController.getInstance().getJsonAccountToken();
        String partnerId = DellController.getInstance().getAccountId();
        Map<String, String> maps = new HashMap<String, String>();
        maps.put( "PartnerID", partnerId );
        maps.put( "TipCategoryID", "85" );
        JSONObject json = new JSONObject( maps );
        // "jsonValue={\"TipCategoryID\":\"85\",\"PartnerID\":\"6\"}&token={\"token\":\"epc15896\"}"
        this.excuteRequest( Urls.GET_TIPS,
                String.format( "jsonValue=%s&token=%s", json.toString(), token ),
                new MethodParams( Methods.GET_ALL_TIP ), activity, handler,
                tipObjPropInfos );

    }

    public void getTipDetail( Activity activity, Handler handler, String tipID,
                              ArrayList<ObjPropInfo> tipObjPropInfos ) {
        String token = DellController.getInstance().getJsonAccountToken();
        this.excuteRequest( Urls.GET_TIP_DETAIL,
                String.format( "tipID=%s&token=%s", tipID, token ),
                new MethodParams( Methods.GET_TIP_DETAIL ), activity, handler,
                tipObjPropInfos );

    }

    public void getAllQuiz( Activity activity, Handler handler,
                            ArrayList<ObjPropInfo> tipObjPropInfos ) {
        String token = DellController.getInstance().getJsonAccountToken();
        String partnerId = DellController.getInstance().getAccountId();
        Map<String, String> maps = new HashMap<String, String>();
        maps.put( "PartnerID", partnerId );
        JSONObject json = new JSONObject( maps );
        // "jsonValue={\"PartnerID\":\"6\"}&token={\"token\":\"epc15896\"}"
        this.excuteRequest( Urls.GET_ALL_QUIZ,
                String.format( "jsonValue=%s&token=%s", json.toString(), token ),
                new MethodParams( Methods.GET_ALL_QUIZ ), activity, handler,
                tipObjPropInfos );

    }
}
